package com.srmt.document.feishu.internal.table.impl.normal;

import com.lark.oapi.service.docx.v1.model.*;
import com.srmt.document.exception.TableException;
import com.srmt.document.feishu.internal.core.BlockContext;
import com.srmt.document.feishu.internal.core.BlockUtils;
import com.srmt.document.feishu.internal.table.model.TableContext;
import com.srmt.document.model.RowData;
import com.srmt.document.model.TableData;
import com.srmt.feishu.client.FeishuClient;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * 普通表格读取操作
 *
 * 封装所有与Normal Table读取相关的操作，包括：
 * - 单元格内容读取
 * - 表格维度获取
 * - 合并单元格信息
 * - 表格数据转换
 *
 * @author srmt
 * @since 3.0.0
 */
public class NormalTableReadOps {

    private static final Logger logger = LoggerFactory.getLogger(NormalTableReadOps.class);

    private final FeishuClient client;

    public NormalTableReadOps(FeishuClient client) {
        if (client == null) {
            throw new IllegalArgumentException("客户端不能为null");
        }
        this.client = client;
    }

    /**
     * 获取单元格内容
     */
    public String getCellContent(TableContext context, int row, int col) throws TableException {
        // 接口定义索引从1开始，需要转换为0-based
        row--;
        col--;

        try {
            BlockContext blockContext = context.getBlockContext();
            String tableBlockId = context.getTableBlockId();

            // 获取表格维度并验证索引
            int[] dimensions = getTableDimensions(context);
            int rowCount = dimensions[0];
            int columnCount = dimensions[1];

            if (row < 0 || row >= rowCount || col < 0 || col >= columnCount) {
                throw new TableException(
                    String.format("单元格索引超出范围: [%d, %d], 表格维度: %dx%d",
                                row + 1, col + 1, rowCount, columnCount));
            }

            // 直接获取单元格Block（不构建整个矩阵）
            Block cellBlock = blockContext.getTableCellBlock(tableBlockId, row, col);
            if (cellBlock == null) {
                return "";
            }

            // 提取单元格内容
            return extractCellContent(blockContext, cellBlock);

        } catch (TableException e) {
            throw e;
        } catch (Exception e) {
            throw new TableException("获取单元格内容失败: " + e.getMessage(),  context.getDocumentId());
        }
    }

    /**
     * 获取表格维度
     */
    public int[] getTableDimensions(TableContext context) throws TableException {
        logger.debug("获取普通表格维度: {}", context.getTableBlockId());

        try {
            // 直接委托给BlockContext
            int[] dimensions = context.getBlockContext().getTableDimensions(
                context.getTableBlockId()
            );

            logger.debug("表格维度: {} x {}", dimensions[0], dimensions[1]);
            return dimensions;

        } catch (Exception e) {
            throw new TableException("获取表格维度失败: " + e.getMessage(),  context.getDocumentId());
        }
    }

    /**
     * 获取表格合并信息
     */
    public TableMergeInfo[] getTableMergeInfo(TableContext context) throws TableException {
        logger.debug("获取普通表格的合并信息: {}", context.getTableBlockId());

        try {
            // 直接委托给BlockContext
            return context.getBlockContext().getTableMergeInfo(
                context.getTableBlockId()
            );

        } catch (Exception e) {
            throw new TableException("获取合并信息失败: " + e.getMessage(),  context.getDocumentId());
        }
    }

    /**
     * 判断单元格是否被合并
     */
    public boolean isMergedCell(TableContext context, int row, int col) throws TableException {
        // 接口定义从1开始，所以需要转换
        row--;
        col--;

        logger.debug("检查普通表格中的单元格[{}, {}]是否已合并", row, col);

        try {
            // 获取合并信息
            TableMergeInfo[] mergeInfo = getTableMergeInfo(context);
            if (mergeInfo == null) {
                return false;
            }

            // 获取表格维度以计算单元格索引
            int[] dimensions = getTableDimensions(context);
            int columnCount = dimensions[1];

            // 计算单元格在mergeInfo数组中的索引
            int cellIndex = row * columnCount + col;
            if (cellIndex >= mergeInfo.length) {
                return false;
            }

            TableMergeInfo merge = mergeInfo[cellIndex];
            if (merge == null) {
                return false;
            }

            // rowSpan或colSpan大于1表示是合并单元格的起始单元格
            // rowSpan或colSpan为0表示是被合并的单元格
            int rowSpan = merge.getRowSpan();
            int colSpan = merge.getColSpan();
            return rowSpan > 1 || colSpan > 1 || rowSpan == 0 || colSpan == 0;

        } catch (Exception e) {
            throw new TableException("(check merged cell: " + e.getMessage());
        }
    }

    /**
     * 转换为TableData对象
     */
    public TableData convertToTableData(TableContext context) throws TableException {
        try {
            int[] dimensions = getTableDimensions(context);
            int rowCount = dimensions[0];
            int columnCount = dimensions[1];

            TableData tableData = new TableData();
            List<RowData> rows = new ArrayList<>();

            // 按需逐行读取（不构建整个矩阵，只在需要时获取单元格）
            for (int row = 1; row <= rowCount; row++) {
                List<String> cells = new ArrayList<>();
                for (int col = 1; col <= columnCount; col++) {
                    // 使用已重构的getCellContent方法
                    cells.add(getCellContent(context, row, col));
                }
                rows.add(new RowData(cells));
            }

            tableData.setRows(rows);

            logger.debug("转换表格数据完成: {} 行 x {} 列", rowCount, columnCount);
            return tableData;

        } catch (TableException e) {
            throw e;
        } catch (Exception e) {
            throw new TableException("转换为TableData失败: " + e.getMessage(), context.getDocumentId());
        }
    }

    // ========== 私有辅助方法 ==========

    /**
     * 提取单元格内容（使用BlockContext）
     *
     * @param blockContext Block上下文
     * @param cellBlock 单元格Block
     * @return 单元格文本内容
     */
    private String extractCellContent(BlockContext blockContext, Block cellBlock) {
        if (cellBlock == null) {
            return "";
        }

        // 单元格可能包含子Block（通常是Text Block）
        List<Block> children = blockContext.findChildrenBlocks(cellBlock.getBlockId());
        if (!children.isEmpty()) {
            StringBuilder content = new StringBuilder();
            for (Block child : children) {
                String text = BlockUtils.extractTextFromBlock(child);
                if (!text.isEmpty()) {
                    if (content.length() > 0) {
                        content.append("\n");
                    }
                    content.append(text);
                }
            }
            return content.toString();
        }

        // 如果没有子Block，尝试直接从单元格Block提取文本
        return BlockUtils.extractTextFromBlock(cellBlock);
    }

    /**
     * 从Block构建TableData
     */
    public TableData buildTableFromBlocks(Block tableBlock, Map<String, Block> blockMap)
            throws TableException {
        if (tableBlock == null || tableBlock.getTable() == null) {
            return new TableData();
        }

        Table table = tableBlock.getTable();
        if (table.getProperty() == null) {
            return new TableData();
        }

        try {
            TableData tableData = new TableData();

            int rowSize = table.getProperty().getRowSize();
            int colSize = table.getProperty().getColumnSize();

            List<RowData> rows = new ArrayList<>();

            // 获取所有单元格内容
            String[] children = tableBlock.getChildren();
            if (children != null && children.length > 0) {
                int cellIndex = 0;
                for (int i = 0; i < rowSize; i++) {
                    List<String> cells = new ArrayList<>();
                    for (int j = 0; j < colSize; j++) {
                        if (cellIndex < children.length) {
                            String cellBlockId = children[cellIndex];
                            Block cellBlock = blockMap.get(cellBlockId);

                            if (cellBlock != null) {
                                // 提取单元格内容
                                String content = extractCellContent(cellBlock, blockMap);
                                cells.add(content);
                            } else {
                                cells.add("");
                            }
                            cellIndex++;
                        } else {
                            cells.add("");
                        }
                    }
                    rows.add(new RowData(cells));
                }
            } else {
                // 创建空表格结构
                for (int i = 0; i < rowSize; i++) {
                    List<String> cells = new ArrayList<>();
                    for (int j = 0; j < colSize; j++) {
                        cells.add("");
                    }
                    rows.add(new RowData(cells));
                }
            }

            tableData.setRows(rows);

            return tableData;

        } catch (Exception e) {
            logger.error("(build table from blocks: {}", e.getMessage());
            return new TableData();
        }
    }

    /**
     * 提取单元格内容（私有辅助方法）
     */
    private String extractCellContent(Block cellBlock, Map<String, Block> blockMap) {
        if (cellBlock == null || cellBlock.getChildren() == null) {
            return "";
        }

        StringBuilder content = new StringBuilder();
        String[] children = cellBlock.getChildren();

        for (String childId : children) {
            Block childBlock = blockMap.get(childId);
            if (childBlock != null) {
                String text = BlockUtils.extractTextFromBlock(childBlock);
                if (!text.isEmpty()) {
                    if (content.length() > 0) {
                        content.append("\n");
                    }
                    content.append(text);
                }
            }
        }

        return content.toString();
    }
}
